import sys
import folium
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtCore import QUrl, QTimer
from PyQt6.QtWebChannel import QWebChannel
import io

class RealTimeMapWidget(QWidget):
    def __init__(self):
        super().__init__()
        # 镇江的江苏大学的经纬度119.515293, 32.199403
        self.latitude = 32.199403
        self.longitude = 119.515293
        # 创建布局
        layout = QVBoxLayout()
        # 创建 QWebEngineView 用于显示地图
        self.web_view = QWebEngineView()
        # 连接 loadFinished 信号到槽函数
        self.web_view.loadFinished.connect(self.on_load_finished)
        layout.addWidget(self.web_view)
        self.setLayout(layout)
        # 生成初始地图
        self.generate_map()
        # 使用 QTimer 替代线程
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.simulate_location_changes)
        self.timer.start(2000)  # 每 2 秒触发一次

    def on_load_finished(self, ok):
        if not ok:
            print("Failed to load map.html")

    def generate_map(self):
        # 创建 folium 地图对象
        m = folium.Map(location=[self.latitude, self.longitude], zoom_start=12)
        # 添加标记到地图上，并添加自定义属性
        self.marker = folium.Marker([self.latitude, self.longitude], icon=folium.Icon(color='red'))
        # 给标记添加自定义属性
        self.marker.add_to(m)
        self.marker._id = 'location_marker'
        # 保存地图为 HTML 文件
        data = io.BytesIO()
        m.save(data, close_file=False)
        html_content = data.getvalue().decode()

        # 创建 QWebChannel 对象
        self.channel = QWebChannel()
        self.web_view.page().setWebChannel(self.channel)
        # 注入 QWebChannel.js 和必要的样式
        html_content = html_content.replace('</head>',
            """
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
    <style>
        .folium-map {
            width: 100%;
            height: 100%;
            position: relative;
        }
        .leaflet-container {
            cursor: crosshair !important;
        }
    </style>
    <script>
        // 全局变量，用于保存 Leaflet 地图对象
        var globalMap;
        // 全局变量，用于保存标记对象
        var marker;

        // 监听 DOM 加载完成事件
        document.addEventListener('DOMContentLoaded', function() {
            // 每隔 100 毫秒检查 Leaflet 地图是否加载完成
            var checkLeaflet = setInterval(function() {
                // 过滤出所有 Leaflet 地图对象
                var maps = Object.values(window).filter(function(value) {
                    return value && value._initHooksCalled && value.getContainer;
                });

                // 如果找到地图对象，则清除定时器并绑定事件
                if (maps.length > 0) {
                    clearInterval(checkLeaflet);
                    globalMap = maps[0];

                    // 创建初始标记
                    marker = L.marker([0, 0], { icon: L.icon({ iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png', iconSize: [25, 41], iconAnchor: [12, 41] }) }).addTo(globalMap);

                    // 绑定地图点击事件
                    globalMap.on('click', function(e) {
                        console.log('Map clicked:', e.latlng.lat, e.latlng.lng);
                        if (typeof QWebChannel !== 'undefined') {
                            new QWebChannel(qt.webChannelTransport, function(channel) {
                                // 调用 Python 端的 handleMapClick 方法处理左键点击事件
                                channel.objects.bridge.handleMapClick(e.latlng.lat, e.latlng.lng, 'left')
                                   .catch(function(error) {
                                        console.error('Error calling handleMapClick:', error);
                                    });
                            });
                        }
                    });

                    // 绑定地图右键点击事件
                    globalMap.on('contextmenu', function(e) {
                        if (typeof QWebChannel !== 'undefined') {
                            new QWebChannel(qt.webChannelTransport, function(channel) {
                                // 调用 Python 端的 handleMapClick 方法处理右键点击事件
                                channel.objects.bridge.handleMapClick(e.latlng.lat, e.latlng.lng, 'right')
                                   .catch(function(error) {
                                        console.error('Error calling handleMapClick:', error);
                                    });
                            });
                        }
                        return false;
                    });
                }
            }, 100);
        });

        // 定义更新标记位置的函数
        window.updateMarkerPosition = function(lat, lng) {
            // 更新标记位置
            marker.setLatLng([lat, lng]);
            // 平移地图视角到新位置
            globalMap.panTo([lat, lng]);
        }
    </script>
            </head>
            """
        )

        # 尝试注释掉这部分代码
        # import re
        # html_content = re.sub(r';+', ';', html_content)  # 移除连续的分号

        # 打印 HTML 内容用于调试
       # print(html_content)

        # 设置 baseUrl 以确保可以加载 qwebchannel.js
        self.web_view.setHtml(html_content, baseUrl=QUrl("qrc:/"))

    def simulate_location_changes(self):
        try:
            # 模拟经纬度变化
            self.latitude += 0.0001
            self.longitude += 0.0001

            # 更新标记位置
            js_code = f"""
            window.updateMarkerPosition({self.latitude}, {self.longitude});
            """
            self.web_view.page().runJavaScript(js_code)
        except Exception as e:
            print(f"Error in simulate_location_changes: {e}")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = RealTimeMapWidget()
    window.show()
    sys.exit(app.exec_())
    